from curses.ascii import isdigit

from django.http import HttpResponseRedirect
from .alitts import ali_tts
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from django.contrib.gis.geos import Point, LineString, Polygon
from geopy.distance import geodesic
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from filer.models.filemodels import File as ModelFile

from .models import *
from .serializers import *
from . import  utils
from .baiduapi import  sendTTSRequest, getTTSResult
from apps.samap.forms import QrcodeForm


@api_view(['GET'])
def get_scenic_area(request, scenicid):
    scenicid = utils.get_scenicid_s(scenicid)
    if scenicid <= 0:
        area = ScenicArea.objects.filter(root=True, is_delete=False).order_by('id').first()
    else:
        area = ScenicArea.objects.get(pk=scenicid)
    if area:
        data = ScenicAreaSerializer(area).data
        data['road_type_list'] = RoadTypeDetailSerializer(RoadType.objects.filter(scenic_area=area,  is_delete=False), many=True).data
        data['maps'] = ScenicAreaMapSerializer(ScenicAreaMap.objects.filter(scenic_area=area, is_delete=False), many=True).data
        if area.firm is not None:
            data['multimap'] = MultimapSerializer(Multimap.objects.filter(firm=area.firm, is_delete=False), many=True).data
        return Response(data)
    return Response(status=status.HTTP_204_NO_CONTENT)


@api_view(['POST'])
def post_scenic_list(request):
    scenicids = request.data['scenicids'].split(",");
    if (len(scenicids) == 0):
        return Response([]);
    areas = ScenicArea.objects.filter(id__in=scenicids, is_delete=False)
    return Response(ScenicAreaSerializer(areas, many=True).data)


@api_view(['GET'])
def get_scenic_area_children(request, scenicid):
    scenic = ScenicArea.objects.get(pk=scenicid)
    scenictype = request.GET.get('scenictype')
    children = utils.get_scenic_area_children(scenic, scenictype)
    return Response([] if not children else children)

@api_view(['GET'])
def get_roads(request, scenicid):
    return Response(RoadTypeDetailSerializer(RoadType.objects.filter(scenic_area__id=scenicid,  is_delete=False), many=True).data)


@api_view(['GET'])
def get_road_detail(request, roadid):
    road = Road.objects.get(pk=roadid)
    related_scenics = RoadScenics.objects.filter(road=road, is_delete=False)
    result = RoadSerializer(road).data
    result['related_scenics'] = []
    for item in related_scenics:
        result['related_scenics'].append(item.scenic.id)

    return Response(result)


@api_view(['POST'])
def post_track(request):
    scenicid = request.data['scenicid']
    user = request.data['user']
    latitude = request.data['latitude']
    longtitude = request.data['longtitude']
    init = request.data.get('init', True)
    scenic_area = ScenicArea.objects.get(pk=scenicid)
    track, is_create = Track.objects.get_or_create(user=user, scenic_area=scenic_area, is_delete=False)
    pnt = Point(float(longtitude), float(latitude))
    is_update = False
    if not track.points:
        track.points = LineString(pnt, pnt)
        is_update = True
    else:
        dist =  geodesic((pnt.y, pnt.x), (track.points[-1][1], track.points[-1][0])).meters
        if dist > 20:
            is_update = True
            track.points.append(pnt.coords)
    if is_update:
        track.save()

    data = TrackSerializer(track).data if init else {}
    data['update'] = is_update
    return Response(data)


@login_required
@api_view(['GET'])
def gdal2tile(request, mapid):
    area_map = ScenicAreaMap.objects.get(pk=mapid)
    if not area_map:
        return Response(status=status.HTTP_204_NO_CONTENT)

    from scripts.gdal2tiles import run_gdal2tiles
    if not run_gdal2tiles(area_map.min_zoom, area_map.max_zoom, utils.get_tiles_img(area_map), utils.get_tiles_full_path(area_map)):
        return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    return redirect('/madmin')


@api_view(['GET'])
def get_icon_legend_list(request, scenicid):
    return Response(IconLegendSerializer(IconLegend.objects.filter(is_delete=False), many=True).data)

@api_view(['GET'])
def get_icon_legend(request, legendid):
    return Response(IconLegendSerializer(IconLegend.objects.get(pk=legendid)).data)

@api_view(['GET'])
def text2speech(request, dbid):
    import time
    scenic = ScenicArea.objects.get(pk=dbid)
    if not scenic or not scenic.audio_detail:
        return Response(status=status.HTTP_204_NO_CONTENT)
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(scenic.audio_detail,'html.parser')
    from .alitts import ali_tts
    speech_url =  ali_tts(soup.get_text())
    if speech_url:
        voice_filename = '%d_%s_speech.mp3' % (scenic.id, scenic.name)
        tmp_file = '/tmp/' + voice_filename
        import wget
        wget.download(speech_url, tmp_file)
        utils.save_scenic_audio(tmp_file, voice_filename, scenic)
        import os
        os.remove(tmp_file)
    return redirect('/madmin')

def qrcode(request):
    # if this is a POST request we need to process the form data
    qrcode_src = ''
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = QrcodeForm(request.POST)
        # check whether it's valid:
        try:
            if form.is_valid():
                scenic_key = form.data['scenic_key']
                scenicid = utils.get_scenicid_s(scenic_key)
                scenic_area = ScenicArea.objects.get(pk=scenicid)
                # return HttpResponseRedirect('/madmin/')
                from common.wxcode import WxCode
                appid = form.data['app_id'] if form.data['app_id'] else settings.DEFAULT_APP_ID
                app_sceret = form.data['app_sceret'] if form.data['app_sceret'] else settings.DEFAULT_APP_SECRET
                obj = WxCode(appid, app_sceret)
                if obj.get_access_token():
                    qrcode_src, qrcode_filepath = utils.get_qrcode_filepath(scenicid)
                    obj.get_code(qrcode_filepath, 'pages/index/index', str(scenicid), 1280)
        except:
            return  render(request, 'qrcode.html', {'form': form, 'qrcode_src': qrcode_src, 'process_error': True, 'scenic_key': scenic_key})
    # if a GET (or any other method) we'll create a blank form
    else:
        if  'key' not in request.GET:
            return HttpResponseRedirect('/madmin/')
        scenic_key = request.GET['key']
        scenicid = utils.get_scenicid_s(scenic_key)
        scenic_area = ScenicArea.objects.get(pk=scenicid)
        dic = {'scenic_name': scenic_area.name, 'scenic_key': scenic_key, 'qrcode_size': QrcodeForm.qrcode_size_c[0][0]}
        form = QrcodeForm(dic, initial=dic)

    return render(request, 'qrcode.html', {'form': form, 'qrcode_src': qrcode_src, 'process_error': False, 'scenic_key': scenic_key})

def cron_task_list(cron_task):
    cron_duration_list = []
    if not cron_task:
        return cron_duration_list
    sep = ';'
    vals = cron_task.split('|')
    for val in vals:
        vs = val.split(sep)
        if len(vs) < 3:
            vs = val.split(',')
        cron_duration_list.append({
            'cron': vs[0],
            'duration': vs[1],
            'advance': vs[2]
        })
    return cron_duration_list

def edit_crontask(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        # check whether it's valid:
        cronid = request.POST.get('cronid')
        cron_task_obj = CronTask.objects.get(pk=cronid)
        cron_task_obj.cron_task = request.POST.get('cron_task')
        cron_task_obj.save()
    # if a GET (or any other method) we'll create a blank form
    else:
        if  'cronid' not in request.GET:
            return HttpResponseRedirect('/madmin/')
        cronid = request.GET['cronid']
        cron_task_obj = CronTask.objects.get(pk=cronid)
    return render(request, 'crontask.html', {'process_error': False, 'cron_task_obj': cron_task_obj, 
        'cron_task_as_list': cron_task_list(cron_task_obj.cron_task), 'task_type_list': CronTask.task_type_list})

@api_view(['GET'])
def get_cron_task_list(request, scenicid):
    task_list = CronTaskSerializer(CronTask.objects.filter(parent_scenic__id=scenicid, is_delete=False, using=True), many=True).data
    return Response(task_list)
